package com.cookor.poi.modules.phy.service;

import com.cookor.poi.common.utils.DateUtils;
import com.cookor.poi.common.utils.IdGen;
import com.cookor.poi.common.utils.JedisUtils;
import com.cookor.poi.common.utils.StringUtils;
import com.cookor.poi.modules.phy.dao.FSchedueDao;
import com.cookor.poi.modules.phy.dao.TOrderDao;
import com.cookor.poi.modules.phy.dao.TPatientDao;
import com.cookor.poi.modules.phy.entity.FSchedue;
import com.cookor.poi.modules.phy.entity.TOrder;
import com.cookor.poi.modules.phy.entity.TPatient;
import com.cookor.poi.modules.phy.schedule.AppointSchedule;
import com.cookor.poi.modules.phy.util.DequeUtil;
import com.cookor.poi.modules.tenant.dao.TTenantDao;
import com.cookor.poi.modules.tenant.entity.TTenant;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class ScheduleService {
    private volatile int orderNo = 0;

    @Autowired
    private TOrderDao tOrderDao;

    @Autowired
    private TPatientDao tPatientDao;

    @Autowired
    private FSchedueDao fSchedueDao;

    @Autowired
    private TTenantDao tTenantDao;

    public void synchronizedCreate(Integer year, String date, Integer index, String title, String beginDate, String endDate, Integer patientId, String openId, Integer tenantId) throws Exception {
        if (tenantId == null || patientId == null || year == null || index == null ||
                StringUtils.isBlank(openId) || StringUtils.isBlank(date) || StringUtils.isBlank(title) ||
                StringUtils.isBlank(beginDate) || StringUtils.isBlank(endDate))
            throw new Exception("参数错误");
        TPatient tPatient = this.tPatientDao.get(patientId.toString());
        if(!tPatient.getOpenId().equals(openId)){
            throw new Exception("参数错误！");
        }
        TOrder orderQuery = new TOrder();
        orderQuery.setTenantId(tenantId);
        orderQuery.setStatus(Integer.valueOf(11));
        orderQuery.setPatientCard(tPatient.getCard());
        orderQuery.setQueryOrderNo(String.valueOf(year).substring(2) + date.split("-")[0]);
        List<TOrder> oldOrders = this.tOrderDao.findList(orderQuery);
        if (oldOrders.size() >= 3)
            throw new Exception("该身份证号本月已取消超过三次，不能再预约了！");
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date bookDate = sdf.parse(year + "-" + date);
//    if (DateUtils.getDistanceOfTwoDate(new Date(), bookDate) > 0.0D)
//      throw new Exception("预约时间段异常");
        sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date parse = sdf.parse(year + "-" + date);
        Calendar c = Calendar.getInstance();
        c.setTime(parse);
        Integer month = Integer.valueOf(c.get(2) + 1);
        Integer day = Integer.valueOf(c.get(5));
        FSchedue query = new FSchedue();
        query.setTenantId(tenantId);
        query.setScheduleYear(year);
        query.setScheduleMonth(month);
        query.setScheduleDay(day);
        List<FSchedue> list = this.fSchedueDao.findList(query);
        if (list.size() > 1 || list.size() == 0)
            throw new Exception("数据异常");
        int no = update(list.get(0).getId(), index, tPatient.getCard(), date, year.toString());
        TTenant tenant = this.tTenantDao.get(tenantId.toString());
        TOrder tOrder = new TOrder();
        tOrder.setDelFlag("0");
        tOrder.setOpenId(openId);
        tOrder.setPatientId(patientId);
        tOrder.setTenantId(tenantId);
        tOrder.setBookDateType(index);
        tOrder.setBookDateDetail(title);
        tOrder.setBookDate(bookDate);
        tOrder.setTenantName(tenant.getTenantName());
        tOrder.setTenantAddress(tenant.getAddress());
        tOrder.setPatientName(tPatient.getPatientName());
        tOrder.setPatientAddress(tPatient.getGender().toString());
        tOrder.setPatientMobile(tPatient.getMobile());
        tOrder.setPatientCard(tPatient.getCard());
        tOrder.setOrderNo(IdGen.getOrderNo());
        tOrder.setStatus(Integer.valueOf(1));
        tOrder.setBookNo(Integer.valueOf(no));
        tOrder.setOfficeName(beginDate + "-" + endDate);
        tOrder.preInsert();
        this.tOrderDao.insert(tOrder);
    }

    public synchronized int update(String id, Integer index, String card, String date, String year) throws Exception {
        String cacheCard = JedisUtils.get(card);
        if (StringUtils.isNotBlank(cacheCard) && cacheCard.equals(date))
            throw new Exception("已预约过该时间段！");
        FSchedue forLock = this.fSchedueDao.get(id);
        Integer no = Integer.valueOf(1);
        Integer count = Integer.valueOf(0);
        if (index == 1) {
            count = forLock.getCountA();
            no = Integer.valueOf(forLock.getTotalA() - count + 1);
            forLock.setCountA(Integer.valueOf(forLock.getCountA() - 1));
            if (no >= forLock.getTotalA()) { // 需要拿到最大的号源数
                no = tOrderDao.getMaxNo(year + "-" + date, index) + 1;
            }
        } else if (index == 2) {
            count = forLock.getCountB();
            forLock.setCountB(Integer.valueOf(forLock.getCountB() - 1));
            no = Integer.valueOf(forLock.getTotalB() - count + 1);
            if (no >= forLock.getTotalB()) {
                no = tOrderDao.getMaxNo(year + "-" + date, index) + 1;
            }
        } else if (index == 3) {
            count = forLock.getCountC();
            forLock.setCountC(Integer.valueOf(forLock.getCountC() - 1));
            no = Integer.valueOf(forLock.getTotalC() - count + 1);
            if (no >= forLock.getTotalC()) {
                no = tOrderDao.getMaxNo(year + "-" + date, index) + 1;
            }
        } else if (index == 4) {
            count = forLock.getCountD();
            forLock.setCountD(Integer.valueOf(forLock.getCountD() - 1));
            no = Integer.valueOf(forLock.getTotalD() - count + 1);
            if (no >= forLock.getTotalD()) {
                no = tOrderDao.getMaxNo(year + "-" + date, index) + 1;
            }
        } else if (index == 5) {
            count = forLock.getCountE();
            forLock.setCountE(Integer.valueOf(forLock.getCountE() - 1));
            no = Integer.valueOf(forLock.getTotalE() - count + 1);
            if (no >= forLock.getTotalE()) {
                no = tOrderDao.getMaxNo(year + "-" + date, index) + 1;
            }
        }
        if (count <= 0)
            throw new Exception("该时间段已约满，请更换时间段");
        this.fSchedueDao.update(forLock);
        JedisUtils.set(card, date, 7200);
        return no;
    }

    @Transactional(readOnly = false, rollbackFor = {Exception.class})
    public void createOrderMod2(Integer year, String date, Integer index, String title, String beginDate, String endDate, Integer patientId, String openId, Integer tenantId) throws Exception {
        boolean flag;
        if (tenantId == null || patientId == null || year == null || index == null ||
                StringUtils.isBlank(openId) || StringUtils.isBlank(date) || StringUtils.isBlank(title) ||
                StringUtils.isBlank(beginDate) || StringUtils.isBlank(endDate))
            throw new Exception("参数错误");
        if (date.split("-")[1].equals(DateUtils.getDay())) {
            flag = true;
        } else {
            flag = false;
        }
        Integer no = null;
        Integer a = null;
        Integer b = null;
        Integer c = null;
        Integer d = null;
        Integer e = null;
        if (index == 1) {
            if (flag) {
                no = DequeUtil.pushA(Integer.valueOf(1));
            } else {
                no = DequeUtil.pushB(Integer.valueOf(1));
            }
            a = Integer.valueOf(1);
        } else if (index == 2) {
            if (flag) {
                no = DequeUtil.pushA(Integer.valueOf(2));
            } else {
                no = DequeUtil.pushB(Integer.valueOf(2));
            }
            b = Integer.valueOf(1);
        } else if (index == 3) {
            if (flag) {
                no = DequeUtil.pushA(Integer.valueOf(3));
            } else {
                no = DequeUtil.pushB(Integer.valueOf(3));
            }
            c = Integer.valueOf(1);
        } else if (index == 4) {
            if (flag) {
                no = DequeUtil.pushA(Integer.valueOf(4));
            } else {
                no = DequeUtil.pushB(Integer.valueOf(4));
            }
            d = Integer.valueOf(1);
        } else if (index == 5) {
            if (flag) {
                no = DequeUtil.pushA(Integer.valueOf(5));
            } else {
                no = DequeUtil.pushB(Integer.valueOf(5));
            }
            e = Integer.valueOf(1);
        }
        if (no == null)
            throw new Exception("该时间段已约满，请更换时间段");
        try {
            TPatient tPatient = (TPatient) this.tPatientDao.get(patientId.toString());
            if (StringUtils.isNotBlank(JedisUtils.get(tPatient.getCard())) && JedisUtils.get(tPatient.getCard()).equals(date))
                throw new Exception("已预约过该时间段！");
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            String bookDateStr = year.toString() + "-" + date;
            Date bookDate = sdf.parse(bookDateStr);
            if (DateUtils.getDistanceOfTwoDate(new Date(), bookDate) > 0.0D)
                throw new Exception("预约时间段异常");
            List<String> cancelThreeList = AppointSchedule.getCancelThreeList();
            if (cancelThreeList.indexOf(tenantId + tPatient.getCard()) != -1)
                throw new Exception("该身份证号本月已取消超过三次，不能再预约了！");
            sdf = new SimpleDateFormat("MM-dd");
            Date parse = sdf.parse(date);
            Calendar cal = Calendar.getInstance();
            cal.setTime(parse);
            Integer month = Integer.valueOf(cal.get(2) + 1);
            Integer day = Integer.valueOf(cal.get(5));
            this.fSchedueDao.cutStock(a, b, c, d, e, tenantId, year, month, day);
            TTenant tenant = (TTenant) this.tTenantDao.get(tenantId.toString());
            TOrder tOrder = new TOrder();
            tOrder.setDelFlag("0");
            tOrder.setOpenId(openId);
            tOrder.setPatientId(patientId);
            tOrder.setTenantId(tenantId);
            tOrder.setBookDateType(index);
            tOrder.setBookDateDetail(title);
            tOrder.setBookDate(bookDate);
            tOrder.setTenantName(tenant.getTenantName());
            tOrder.setTenantAddress(tenant.getAddress());
            tOrder.setPatientName(tPatient.getPatientName());
            tOrder.setPatientAddress(tPatient.getGender().toString());
            tOrder.setPatientMobile(tPatient.getMobile());
            tOrder.setPatientCard(tPatient.getCard());
            tOrder.setOrderNo(IdGen.getOrderNo());
            tOrder.setStatus(Integer.valueOf(1));
            tOrder.setBookNo(no);
            tOrder.setOfficeName(beginDate + "-" + endDate);
            tOrder.preInsert();
            this.tOrderDao.insert(tOrder);
            JedisUtils.set(tPatient.getCard(), date, 3600);
        } catch (Exception ex) {
            throw ex;
        } finally {
            if (index == 1) {
                if (flag) {
                    DequeUtil.addA(Integer.valueOf(1), no);
                } else {
                    DequeUtil.addB(Integer.valueOf(1), no);
                }
            } else if (index == 2) {
                if (flag) {
                    DequeUtil.addA(Integer.valueOf(2), no);
                } else {
                    DequeUtil.addB(Integer.valueOf(2), no);
                }
            } else if (index == 3) {
                if (flag) {
                    DequeUtil.addA(Integer.valueOf(3), no);
                } else {
                    DequeUtil.addB(Integer.valueOf(3), no);
                }
            } else if (index == 4) {
                if (flag) {
                    DequeUtil.addA(Integer.valueOf(4), no);
                } else {
                    DequeUtil.addB(Integer.valueOf(4), no);
                }
            } else if (index == 5) {
                if (flag) {
                    DequeUtil.addA(Integer.valueOf(5), no);
                } else {
                    DequeUtil.addB(Integer.valueOf(5), no);
                }
            }
        }
    }
}
